package com.boarsoft.boar.code.mac.flow.generator;

import java.io.IOException;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;

import org.apache.commons.lang.StringUtils;
import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.Velocity;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.boarsoft.boar.code.bean.biz.BeanMappingBiz;
import com.boarsoft.boar.code.entity.BeanMapping;
import com.boarsoft.boar.code.entity.WrapHandlerInfo;
import com.boarsoft.boar.code.mac.flow.biz.WrapHandlerInfoBiz;


@Component
public class WrapHandlerGenerator {
    @Autowired
    private WrapHandlerInfoBiz wrapHandlerInfoBiz;

    @Autowired
    private BeanMappingBiz beanMappingBiz;
    /* public static void main(String[] args) throws IOException {

        //1.handler全名
        String absoluteHandlerName="com.scrcu.core.indv.mac.handler.OpenAccountWrapHandler";
        //2.映射列表
        List<CheckInMapping> checkInMappingList=new ArrayList<>();
        CheckInMapping checkInMappingA=new CheckInMapping();
        //目标对象
        checkInMappingA.setDest("demo.scrcu.core.intd.bean.User");
        //来源对象
        checkInMappingA.setSrc("com.scrcu.indv.req.OpenRequest");
        //输入映射列表
        List<CheckInMappingDetl> checkInMappingDetlList =new ArrayList<>();
        CheckInMappingDetl checkInMappingDetl1 =new CheckInMappingDetl();
        checkInMappingDetl1.setDestType("java.lang.String");
        checkInMappingDetl1.setDestObj("user");
        checkInMappingDetl1.setDestField("userId");
        checkInMappingDetl1.setSrcArea("input");
        checkInMappingDetl1.setSrcType("java.lang.String");
        checkInMappingDetl1.setSrcObj("openRequest");
        checkInMappingDetl1.setSrcField("userId");
        checkInMappingDetlList.add(checkInMappingDetl1);
        CheckInMappingDetl checkInMappingDetl2 =new CheckInMappingDetl();
        checkInMappingDetl2.setDestType("java.lang.String");
        checkInMappingDetl2.setDestObj("user");
        checkInMappingDetl2.setDestField("userName");
        checkInMappingDetl2.setSrcArea("context");
        checkInMappingDetl2.setSrcType("java.lang.String");
        checkInMappingDetl2.setSrcField("userName");
        checkInMappingDetlList.add(checkInMappingDetl2);
        checkInMappingA.setCheckInMappingDetlList(checkInMappingDetlList);
        checkInMappingList.add(checkInMappingA);
        //3.
        CheckOutMapping checkOutMapping=new CheckOutMapping();
        checkOutMapping.setSrc("com.scrcu.indv.component.resp.AResponse");
        checkOutMapping.setDest("com.scrcu.indv.req.OpenResponse");
        List<CheckOutMappingDetl> checkOutMappingDetlList =new ArrayList<>();
        CheckOutMappingDetl checkOutMappingDetl1=new CheckOutMappingDetl();
        checkOutMappingDetl1.setDestType("java.lang.String");
        checkOutMappingDetl1.setDestField("userId");
        checkOutMappingDetl1.setDestArea("output");
        checkOutMappingDetl1.setSrcType(checkOutMapping.getSrc());
        checkOutMappingDetl1.setSrcField("userId");
        checkOutMappingDetlList.add(checkOutMappingDetl1);
        CheckOutMappingDetl checkOutMappingDetl2=new CheckOutMappingDetl();
        checkOutMappingDetl2.setDestType("demo.scrcu.core.intd.bean.User");
        checkOutMappingDetl2.setDestObj("user");
        checkOutMappingDetl2.setDestField(StringUtils.capitalize("user"));
        checkOutMappingDetl2.setDestArea("context");
        checkOutMappingDetl2.setSrcType(checkOutMapping.getSrc());
        checkOutMappingDetl2.setSrcField("user");
        checkOutMappingDetlList.add(checkOutMappingDetl2);
        checkOutMapping.setCheckOutMappingDetlList(checkOutMappingDetlList);

        //3.目标组件方法
        generate(absoluteHandlerName,checkInMappingList,checkOutMapping);
    }*/
    public String generate(String code, String key,int type, String appId) throws IOException {
       //1.映射列表
       List<CheckInMapping> checkInMappingList=new ArrayList<>();
       //2.入参
       List<WrapHandlerInfo> wrapHandlerCheckInInfos=wrapHandlerInfoBiz.find(code, key, type, appId);
       //3.映射
       for(WrapHandlerInfo wrapHandlerInfo:wrapHandlerCheckInInfos){
           List<BeanMapping> checkInBeanMappings = beanMappingBiz.listFromCodeId(wrapHandlerInfo.getId(),"0");
           if(checkInBeanMappings!=null&&checkInBeanMappings.size()>0) {
               CheckInMapping checkInMappingTmp=new CheckInMapping();
               //目标对象
               checkInMappingTmp.setDest(checkInBeanMappings.get(0).getToType());
               //来源对象
               checkInMappingTmp.setSrc(checkInBeanMappings.get(0).getFromType());
               //输入映射列表
               List<CheckInMappingDetl> checkInMappingDetlList = new ArrayList<>();
               for (BeanMapping beanMapping : checkInBeanMappings) {
                   CheckInMappingDetl checkInMappingDetl1 = new CheckInMappingDetl();
                   checkInMappingDetl1.setDestType(beanMapping.getToPropType());
                   checkInMappingDetl1.setDestObj(beanMapping.getToObj());
                   checkInMappingDetl1.setDestField(beanMapping.getToProp());
                   checkInMappingDetl1.setSrcArea("input");
                   checkInMappingDetl1.setSrcType(beanMapping.getFromPropType());
                   checkInMappingDetl1.setSrcObj(beanMapping.getFromObj());
                   checkInMappingDetl1.setSrcField(beanMapping.getFromProp());
                   checkInMappingDetlList.add(checkInMappingDetl1);
               }
               checkInMappingTmp.setCheckInMappingDetlList(checkInMappingDetlList);
               checkInMappingList.add(checkInMappingTmp);
           }
       }
       //2.获得CheckOut方法
       WrapHandlerInfo wrapHandlerCheckOutInfos=wrapHandlerInfoBiz.find(code, key, type, appId).get(0);
       List<BeanMapping> checkOutBeanMappings = beanMappingBiz.listFromCodeId(wrapHandlerCheckOutInfos.getId(),"1");

       CheckOutMapping checkOutMapping=new CheckOutMapping();
        if(checkOutBeanMappings!=null&&checkOutBeanMappings.size()>0){
            checkOutMapping.setSrc(checkOutBeanMappings.get(0).getFromType());
            checkOutMapping.setDest(checkOutBeanMappings.get(0).getToType());
            List<CheckOutMappingDetl> checkOutMappingDetlList =new ArrayList<>();
            for(BeanMapping beanMapping : checkOutBeanMappings) {
                CheckOutMappingDetl checkOutMappingDetl1=new CheckOutMappingDetl();
                checkOutMappingDetl1.setDestType(beanMapping.getToPropType());
                checkOutMappingDetl1.setDestField(beanMapping.getToProp());
                checkOutMappingDetl1.setDestArea("output");
                checkOutMappingDetl1.setSrcType(checkOutMapping.getSrc());
                checkOutMappingDetl1.setSrcField(beanMapping.getFromProp());
                checkOutMappingDetlList.add(checkOutMappingDetl1);
            }
            checkOutMapping.setCheckOutMappingDetlList(checkOutMappingDetlList);
        }
        //3.目标组件方法
        return generate(code,checkInMappingList,checkOutMapping);
    }

    protected String generate(String absoluteName, List<CheckInMapping> checkInMappingList,CheckOutMapping checkOutMapping) throws IOException {
        Properties prop = new Properties();
        prop.put("file.resource.loader.class", "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader");
        Velocity.init(prop);
        //封装模板数据
        Map<String, Object> map = new HashMap<>();
        String packageNm=absoluteName.substring(0,absoluteName.lastIndexOf("."));
        String classNm=absoluteName.substring(absoluteName.lastIndexOf(".")+1);
        if(checkInMappingList!=null&&checkInMappingList.size()>0) {
            for (CheckInMapping checkInMappingN : checkInMappingList) {
                checkInMappingN.setDestObj(checkInMappingN.getDest().substring(checkInMappingN.getDest().lastIndexOf("." ) + 1).toLowerCase());
                checkInMappingN.setSrcObj(checkInMappingN.getSrc().substring(checkInMappingN.getSrc().lastIndexOf("." ) + 1).toLowerCase());
                for (CheckInMappingDetl checkInMappingDetl : checkInMappingN.getCheckInMappingDetlList()) {
                    checkInMappingDetl.setDestField(StringUtils.capitalize(checkInMappingDetl.getDestField()));
                    checkInMappingDetl.setSrcField(StringUtils.capitalize(checkInMappingDetl.getSrcField()));
                }
            }
            map.put("checkInMappingList", checkInMappingList);
        }
        if(checkOutMapping.getSrc()!=null) {
            checkOutMapping.setSrcObj(checkOutMapping.getSrc().substring(checkOutMapping.getSrc().lastIndexOf("." ) + 1).toLowerCase());
            checkOutMapping.setDestObj(checkOutMapping.getDest().substring(checkOutMapping.getDest().lastIndexOf("." ) + 1).toLowerCase());
            for (CheckOutMappingDetl checkOutMappingDetl : checkOutMapping.getCheckOutMappingDetlList()) {

                checkOutMappingDetl.setSrcObj(checkOutMapping.getSrc().substring(checkOutMapping.getSrc().lastIndexOf("." ) + 1).toLowerCase());
                checkOutMappingDetl.setSrcField(StringUtils.capitalize(checkOutMappingDetl.getSrcField()));
                checkOutMappingDetl.setDestObj(checkOutMapping.getDest().substring(checkOutMapping.getDest().lastIndexOf("." ) + 1).toLowerCase());
                checkOutMappingDetl.setDestField(StringUtils.capitalize(checkOutMappingDetl.getDestField()));

            }
            map.put("checkOutMapping",checkOutMapping);
        }else{
            map.put("checkOutMapping",null);
        }
        //1.包路径
        map.put("package", packageNm);
        //2.映射列表
        map.put("inputParamlength", checkInMappingList.size());
        //3.wrapHandler类名
        map.put("className", classNm);

        VelocityContext context = new VelocityContext(map);
        StringWriter sw = new StringWriter();
        Template tpl = Velocity.getTemplate("template/Wrapper.java.vm", "UTF-8");
        tpl.merge(context, sw);//将数据context合并入模板tpl中，获得的数据写入sw
       /* String path="D:\\"+classNm+".java";
        OutputStream ouputStream = new FileOutputStream(path);
        IOUtils.write(sw.toString(), ouputStream, "UTF-8");
        IOUtils.closeQuietly(sw);*/
        return sw.toString();

    }
}
